package com.whmskj.xjlhbc.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.whmskj.xjlhbc.core.AjaxResult;
import com.whmskj.xjlhbc.domain.CorpMember;
import com.whmskj.xjlhbc.domain.Js05dVarietyMaintenance;
import com.whmskj.xjlhbc.domain.ScProductionOrders;
import com.whmskj.xjlhbc.dto.OrderAddDto;
import com.whmskj.xjlhbc.dto.OrderReportDto;
import com.whmskj.xjlhbc.dto.OrderUpdateDto;
import com.whmskj.xjlhbc.mapper.Js05dVarietyMaintenanceMapper;
import com.whmskj.xjlhbc.mapper.ScProductionOrdersMapper;
import com.whmskj.xjlhbc.service.IPersonnelManagementDataSheetsService;
import com.whmskj.xjlhbc.service.OrdersService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: Sakura
 * @Date: 2025/8/20 9:16
 * &#064;Version:  v1.0.0
 * @Description: TODO
 **/
@Slf4j
@Service
public class OrdersServiceImpl implements OrdersService {

    @Autowired
    private ScProductionOrdersMapper scProductionOrdersMapper;
    @Autowired
    private Js05dVarietyMaintenanceMapper varietyMapper;

    /**
     * 新增订单
     * @param request
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addOrder(OrderAddDto request) {
        try {
            // 生成订单编号
            String orderNumber = generateOrderNumber();
            // 创建订单对象
            ScProductionOrders order = new ScProductionOrders();
            // 订单编号
            order.setOrderNumber(orderNumber);
            // 品号
            order.setNoNo3(request.getNoNo3());
            // 米数
            order.setNumber(request.getNumber());
            // 交付日期
            order.setDateOfDelivery(request.getDateOfDelivery());
            // 下单日期
            order.setNextDay(DateUtil.today());
            // 备注
            order.setRemarks(request.getRemarks());
            order.setModifyer(getCorpMember().getMemberId());
            order.setSynchronisingFolderFailedSS(getCorpMember().getMemberId());
            order.setOrderStatus("已下单");
            order.setCreated(DateUtil.now());
            order.setModified(DateUtil.now());
            order.setTypeOfOrder(request.getTypeOfOrder());
            order.setProductName(request.getProductName());
            order.setNomenclatures3(request.getProductName());
            // 插入订单
            int result = scProductionOrdersMapper.insert(order);
            if (result > 0) {
                return AjaxResult.success("订单创建成功", order);
            } else {
                return AjaxResult.error("订单创建失败");
            }
        } catch (Exception e) {
            throw new RuntimeException("创建订单失败: " + e.getMessage());
        }
    }

    private CorpMember getCorpMember(){
        IPersonnelManagementDataSheetsService personnel = SpringUtil.getBean(IPersonnelManagementDataSheetsService.class);
        return personnel.getCorpMemberByLogin();
    }

    // 生成订单编号的方法
    private String generateOrderNumber() {
        // 获取当前日期，格式为YYMMDD（例如250802）
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd");
        String datePart = dateFormat.format(new Date());

        // 查询当天已有的订单数量，用于生成顺序号
        long  orderCount = getTodayOrderCount(datePart);

        // 生成3位顺序号（001, 002, ...）
        String sequencePart = String.format("%03d", orderCount + 1);

        // 组合成完整的订单编号
        return datePart + sequencePart;
    }

    // 查询当天订单数量的方法
    private long getTodayOrderCount(String datePart) {
        QueryWrapper<ScProductionOrders> queryWrapper = new QueryWrapper<>();
        queryWrapper.likeRight("orderNumber", datePart); // 查询以当天日期开头的订单
        return scProductionOrdersMapper.selectCount(queryWrapper);
    }

    /**
     * 获取品号列表
     * @param noNo3
     * @return
     */
    @Override
    public List<Js05dVarietyMaintenance> getVarietyList(String noNo3) {
        List<Js05dVarietyMaintenance> list = scProductionOrdersMapper.selectByKeyword(noNo3);
        return list;
    }

    @Override
    public List<Js05dVarietyMaintenance> listSczVariety(String noNo3) {
        List<Js05dVarietyMaintenance> list = scProductionOrdersMapper.selectByKeywordScz(noNo3);
        return list;
    }

    /**
     * 删除订单
     * @param orderNumber
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult deleteByOrderNumber(String orderNumber) {
        try {
            // 验证订单号是否为空
            if (StringUtils.isBlank(orderNumber)) {
                return AjaxResult.error("订单号不能为空");
            }

            // 检查订单是否存在
            ScProductionOrders order = scProductionOrdersMapper.selectByOrderNumber(orderNumber);
            if (order == null) {
                return AjaxResult.error("订单不存在");
            }

            // 检查订单状态是否为"已下单"
            if (!"已下单".equals(order.getOrderStatus())) {
                return AjaxResult.error("只有【已下单】状态的订单才能删除");
            }

            // 执行删除操作
            int result = scProductionOrdersMapper.deleteByOrderNumber(orderNumber);

            if (result > 0) {
                log.info("订单 {} 删除成功", orderNumber);
                return AjaxResult.success("订单删除成功");
            } else {
                return AjaxResult.error("订单删除失败");
            }
        } catch (Exception e) {
            log.error("删除订单异常，订单号：{}", orderNumber, e);
            throw new RuntimeException("删除订单失败: " + e.getMessage());
        }
    }

    /**
     * 修改订单
     * @param updateDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateOrder(OrderUpdateDto updateDto) {
        try {
            // 验证订单是否存在
            ScProductionOrders existingOrder = scProductionOrdersMapper.selectByOrderNumber(updateDto.getOrderNumber());
            if (existingOrder == null) {
                return AjaxResult.error("订单不存在");
            }

            // 验证品号是否存在（如果需要）
            if (StringUtils.isNotBlank(updateDto.getNoNo3())) {
                Js05dVarietyMaintenance variety = varietyMapper.selectOne(
                        new QueryWrapper<Js05dVarietyMaintenance>()
                                .eq("noNo3", updateDto.getNoNo3())
                );

                if (variety == null) {
                    return AjaxResult.error("品号不存在");
                }

                // 如果前端没有传递品名，可以根据品号自动获取
                if (StringUtils.isBlank(updateDto.getNomenclatures())) {
                    updateDto.setNomenclatures(variety.getNomenclatures());
                }
            }

            // 创建订单更新对象
            ScProductionOrders order = new ScProductionOrders();

            // 订单号
            order.setOrderNumber(updateDto.getOrderNumber());
            // 品号
            order.setNoNo3(updateDto.getNoNo3());
            // 品名
            order.setNomenclatures3(updateDto.getNomenclatures());
            // 数量
            order.setNumber(updateDto.getNumber());
            // 交付日期
            order.setDateOfDelivery(updateDto.getDateOfDelivery());
            // 备注
            order.setRemarks(updateDto.getRemarks());

            // 执行更新操作
            int result = scProductionOrdersMapper.updateByOrderNumber(order);

            if (result > 0) {
                return AjaxResult.success("订单更新成功");
            } else {
                return AjaxResult.error("订单更新失败");
            }
        } catch (Exception e) {
            log.error("更新订单异常", e);
            throw new RuntimeException("更新订单失败: " + e.getMessage());
        }
    }

    /**
     * 获取订单报表
     * @return
     */
    @Override
    public AjaxResult getOrderReport() {
        try {
            OrderReportDto report = new OrderReportDto();

            // 1. 获取订单状态统计
            OrderReportDto.OrderStats orderStats = getOrderStats();
            report.setRealTimeStats(orderStats);

            // 2. 获取合计统计
            OrderReportDto.SummaryStats summaryStats = getSummaryStats();
            report.setSummary(summaryStats);

            // 3. 获取月度统计（最近3个月）
            List<OrderReportDto.MonthlyStats> monthlyStats = getMonthlyStats(3);
            report.setMonthlyStats(monthlyStats);

            return AjaxResult.success("报表获取成功", report);
        } catch (Exception e) {
            log.error("获取订单报表异常", e);
            return AjaxResult.error("获取报表失败: " + e.getMessage());
        }
    }

    @Override
    public Js05dVarietyMaintenance getVarietyById(String id) {
        Js05dVarietyMaintenance js05dVarietyMaintenance = Optional.ofNullable(varietyMapper.selectById(id)).orElseGet(Js05dVarietyMaintenance::new);
        return js05dVarietyMaintenance;
    }

    @Override
    public Js05dVarietyMaintenance getVarietyByNoNo3(String noNo3) {
        LambdaQueryWrapper<Js05dVarietyMaintenance> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Js05dVarietyMaintenance::getNoNo3, noNo3).last("limit 1");
        Js05dVarietyMaintenance js05dVarietyMaintenance = Optional.ofNullable(varietyMapper.selectOne(wrapper)).orElseGet(Js05dVarietyMaintenance::new);
        return js05dVarietyMaintenance;
    }

    // 获取订单状态统计
    private OrderReportDto.OrderStats getOrderStats() {
        List<Map<String, Object>> statusCounts = scProductionOrdersMapper.countByStatus();
        OrderReportDto.OrderStats stats = new OrderReportDto.OrderStats();

        for (Map<String, Object> item : statusCounts) {
            String status = (String) item.get("orderStatus");
            Integer count = ((Long) item.get("count")).intValue();
            Double meters = ((BigDecimal) item.get("totalMeters")).doubleValue() / 10000; // 转换为万米

            switch (status) {
                case "待接单":
                    stats.setPendingAccept(meters);
                    stats.setPendingAcceptCount(count);
                    break;
                case "待生产":
                    stats.setPendingProduce(meters);
                    stats.setPendingProduceCount(count);
                    break;
                case "生产中":
                    stats.setInProduction(meters);
                    stats.setInProductionCount(count);
                    break;
            }
        }

        return stats;
    }

    // 获取合计统计
    private OrderReportDto.SummaryStats getSummaryStats() {
        Map<String, Object> resultMap = scProductionOrdersMapper.countUncompletedAndOverdue();
        // 由于我们使用了 @MapKey("statType")，resultMap 的键是 "summary"
        Map<String, Object> result = (Map<String, Object>) resultMap.get("summary");

        OrderReportDto.SummaryStats stats = new OrderReportDto.SummaryStats();

        // 修复类型转换问题：先转为 BigDecimal，再转为 int
        stats.setTotalUncompletedCount(((BigDecimal) result.get("uncompletedCount")).intValue());
        stats.setTotalUncompletedMeters(((BigDecimal) result.get("uncompletedMeters")).doubleValue() / 10000);
        stats.setOverdueCount(((BigDecimal) result.get("overdueCount")).intValue());
        stats.setOverdueMeters(((BigDecimal) result.get("overdueMeters")).doubleValue() / 10000);

        return stats;
    }

    // 获取月度统计
    private List<OrderReportDto.MonthlyStats> getMonthlyStats(int months) {
        List<Map<String, Object>> monthlyData = scProductionOrdersMapper.countByMonth(months);
        List<OrderReportDto.MonthlyStats> statsList = new ArrayList<>();

        for (Map<String, Object> item : monthlyData) {
            OrderReportDto.MonthlyStats stats = new OrderReportDto.MonthlyStats();

            stats.setMonth((String) item.get("month"));
            // 修复类型转换问题：使用 Number 接口作为中间类型
            stats.setOrderCount(((Number) item.get("orderCount")).intValue());
            stats.setOrderMeters(((Number) item.get("orderMeters")).doubleValue() / 10000);
            stats.setCompletedCount(((Number) item.get("completedCount")).intValue());
            stats.setCompletedMeters(((Number) item.get("completedMeters")).doubleValue() / 10000);

            statsList.add(stats);
        }

        return statsList;
    }

}
